package com.teamtwoseven.todo;

import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.DatePickerDialog;
import android.app.Dialog;
import android.app.TimePickerDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.DatePicker;
import android.widget.EditText;
import android.widget.ArrayAdapter;
import android.widget.RadioButton;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.TimePicker;

/**
 * This screen allows the user to edit an existing item.
 * 
 * @author teamtwoseven
 */
public class EditItem extends Activity implements OnClickListener {

	private static final int DATE_DIALOG_ID = 0;
	private static final int TIME_DIALOG_ID = 1;
	
	private long userRowID, itemRowID;
	private Storage storage;
	private Button bSave, bCancel, bSettings, bLogout, bSetDate, bSetTime;
	private Button bLocation;
	private RadioButton rbOnce, rbDaily, rbWeekly, rbMonthly;
	private EditText etItemName, etDescription;
	private Spinner spinner;
	private boolean done;
	private long deadline;
	private String location;
	
	private DatePickerDialog.OnDateSetListener mDateSetListener;
	private TimePickerDialog.OnTimeSetListener mTimeSetListener;

	/**
	 * Called when the activity is first created.
	 * 
	 * @param savedInstanceState
	 * 			allows instance data to be stored
	 */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.edit_item);

		getUser(); // sets userRowID, storage, and the welcome text

		bSave = (Button) findViewById(R.id.editItem_bSave);
		bCancel = (Button) findViewById(R.id.editItem_bCancel);
		bSettings = (Button) findViewById(R.id.editItem_bSettings);
		bLogout = (Button) findViewById(R.id.editItem_bLogout);
		bSetDate = (Button) findViewById(R.id.editItem_bSetDate);
		bSetTime = (Button) findViewById(R.id.editItem_bSetTime);
		bLocation = (Button) findViewById(R.id.editItem_bLocation);
		rbOnce = (RadioButton) findViewById(R.id.editItem_rbOnce);
		rbDaily = (RadioButton) findViewById(R.id.editItem_rbDaily);
		rbWeekly = (RadioButton) findViewById(R.id.editItem_rbWeekly);
		rbMonthly = (RadioButton) findViewById(R.id.editItem_rbMonthly);
		etItemName = (EditText) findViewById(R.id.editItem_etItemName);
		etDescription = (EditText) findViewById(R.id.editItem_etDescription);

		spinner = (Spinner) findViewById(R.id.editItem_spinner);
		ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
			this, R.array.category_type,
			android.R.layout.simple_spinner_item);
		adapter.setDropDownViewResource(
			android.R.layout.simple_spinner_dropdown_item);
		spinner.setAdapter(adapter);
		
		showItem();

		bSave.setOnClickListener(this);
		bCancel.setOnClickListener(this);
		bSettings.setOnClickListener(this);
		bLogout.setOnClickListener(this);
		bSetDate.setOnClickListener(this);
		bSetTime.setOnClickListener(this);
		bLocation.setOnClickListener(this);
		
		mDateSetListener = new DatePickerDialog.OnDateSetListener() {
			// called when date is set by the user
			public void onDateSet(DatePicker view, int year, int month,
				int day) {
				
				bSetDate.setText((month + 1) + "/" + day + "/" + year);
			}
		};
		
		mTimeSetListener = new TimePickerDialog.OnTimeSetListener() {
			// called when time is set by the user
			public void onTimeSet(TimePicker view, int hour, int minute) {
				bSetTime.setText(formatTime(hour, minute));
			}
		};
	}

	/**
	 * Handles button clicks
	 * 
	 * @param arg0
	 * 			the element that was clicked
	 */
	public void onClick(View arg0) {
		if (arg0 == bSave) {
			String name = etItemName.getText().toString();
			String description = etDescription.getText().toString();

			// Verify input and update item if input is valid
			if (verify(name, description)) {
				String category = spinner.getSelectedItem().toString();
				String date = bSetDate.getText().toString();
				String frequency = "Once";
				
				if (rbDaily.isChecked()) {
					frequency = "Daily";
				}
				else if (rbWeekly.isChecked()) {
					frequency = "Weekly";
				}
				else if (rbMonthly.isChecked()) {
					frequency = "Monthly";
				}
				
				try {
					deadline = new SimpleDateFormat(
						"MM/dd/yyyy'T'hh:mma").parse(date +
						"T" + bSetTime.getText()).getTime();
				} catch (ParseException e) {
					e.printStackTrace();
				}
				
				storage.updateItem(userRowID, itemRowID, name, description,
					category, deadline, frequency, location, "" + done);
				finish();
			}
		}
		else if (arg0 == bCancel) {
			// End this Activity and Return to Main Screen
			finish();
		}
		else if (arg0 == bSettings) {
			// End this activity; Main will launch the settings screen
			setResult(2);
			finish();
		}
		else if (arg0 == bLogout) {
			// End this activity; Main will launch the login screen
			setResult(1);
			finish();
		}
		else if (arg0 == bSetDate) {
			showDialog(DATE_DIALOG_ID);
		}
		else if (arg0 == bSetTime) {
			showDialog(TIME_DIALOG_ID);
		}
		else if (arg0 == bLocation) {
			//get address from user
			final EditText input = new EditText(this);
			AlertDialog alert = new AlertDialog.Builder(EditItem.this).create();
			alert.setView(input);
			alert.setTitle("Enter A Location for Item");
			alert.setMessage("City, State/Address/Name of Location (i.e. Virginia Beach)");
			alert.setButton("Select Location", new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int which) {
					// TODO Auto-generated method stub
					location = input.getText().toString();
					bLocation.setText(location);
				}
			});
			alert.show();
		}
	}

	/**
	 * Verifies the given name, and description are valid, and ensures a
	 * deadline has been set. If any of this is not true, displays a dialog
	 * telling the user what needs to be done.
	 * 
	 * @param name
	 * 			an item name
	 * @param description
	 * 			an item description
	 * @return true if the parameters are valid and a day/date and time have
	 * 			been chosen; false otherwise
	 */
	private boolean verify(String name, String description) {
		boolean success = true;
		String feedback = "";

		if (!validText(name)) {
			feedback += "Enter a name for this item\n";
			success = false;
		}
		else if (name.length() > 34) {
			feedback += "Item name must be less than 35 characters\n";
			success = false;
		}
		if (!validText(description)) {
			feedback += "Enter a description\n";
			success = false;
		}
		if (bSetDate.getText().toString().equals("Date")) {
			feedback += "Choose a date\n";
			success = false;
		}
		if (bSetTime.getText().toString().equals("Time")) {
			feedback += "Choose a time\n";
			success = false;
		}
		if (!rbOnce.isChecked() && !rbDaily.isChecked() &&
			!rbWeekly.isChecked() && !rbMonthly.isChecked()) {
			
			feedback += "Select how often this item will occur\n";
			success = false;
		}
		if (!success) {
			// Display which parameters are invalid
			popupDialog(feedback, false);
		}
		return success;
	}

	/**
	 * Verifies the given text is not empty or all whitespace.
	 * 
	 * @param text
	 * 			a String
	 * @return true if the text is not empty or all whitespace, false otherwise
	 */
	private boolean validText(String text) {
		return !text.replaceAll("\\s+", "").equals("");
	}

	/**
	 * Displays a dialog listing the given message and an OK button. If done is
	 * true, clicking OK ends this Activity. Otherwise OK closes the dialog.
	 * 
	 * @param message
	 * 			text to display to the user
	 * @param done
	 * 			if true, clicking OK finishes the Activity; if false, OK just
	 * 			closes the dialog
	 */
	private void popupDialog(String message, final boolean done) {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);

		builder.setMessage(message);
		builder.setCancelable(false);
		builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int id) {
				dialog.cancel();
				if (done) {
					finish();
				}
			}
		});
		builder.show();
	}
	
	protected Dialog onCreateDialog(int id) {
		Calendar c = Calendar.getInstance();
		switch (id) {
		case DATE_DIALOG_ID:
			return new DatePickerDialog(this, mDateSetListener,
			c.get(Calendar.YEAR), c.get(Calendar.MONTH),
			c.get(Calendar.DAY_OF_MONTH));
		case TIME_DIALOG_ID:
			return new TimePickerDialog(this, mTimeSetListener,
				(c.get(Calendar.HOUR_OF_DAY)+21)%24,
				(c.get(Calendar.MINUTE)+30)%60, false);
		}
		return null;
	}

	/**
	 * Gets the row ID of the current user's stored info. Also sets the welcome
	 * text to display the user's full name if it is less than 22 characters;
	 * up to 22 characters of the user's first name otherwise.
	 */
	private void getUser() {
		userRowID = Singleton.getInstance().getUserRowID();
		storage = new Storage(EditItem.this);
		
		String name = storage.getFullName(userRowID);

		if (name.length() > 22) {
			name = name.substring(0, 22);
			if (name.substring(1, 21).contains(" ")) {
				name = name.substring(0, name.indexOf(" "));
			}
		}

		TextView tvWelcome = (TextView) findViewById(R.id.editItem_tvWelcome);
		tvWelcome.setText("Welcome, " + name + "!");
	}

	/**
	 * Gets the row ID of the item being edited and initializes the inputs on
	 * the screen to that item's info.
	 */
	private void showItem() {
		Item item;
		String category, time; // time is the time stored as part of deadline
		String frequency;
		int spinnerSelection = 0; // 0 corresponds to the Personal category
		itemRowID = Singleton.getInstance().getItemRowID();
		
		item = storage.getItem(userRowID, itemRowID);
		
		// Set the inputs on the page to match the current info for this item
		etItemName.setText(item.getName());
		etDescription.setText(item.getDescription());
		deadline = item.getDeadline();
		location = item.getLocation();
		
		frequency = item.getFrequency();
		
		if (frequency.equals("Daily")) {
			rbDaily.setChecked(true);
		}
		else if (frequency.equals("Weekly")) {
			rbWeekly.setChecked(true);
		}
		else if (frequency.equals("Monthly")) {
			rbMonthly.setChecked(true);
		}
		else {
			rbOnce.setChecked(true);
		}
		
		time = new SimpleDateFormat("HH:mma").format(new Date(deadline));
			
		bSetDate.setText(
				new SimpleDateFormat("MM/dd/yyyy").format(new Date(deadline)));
				
		bSetTime.setText(formatTime(new Integer(time.substring(0,2)),
			new Integer(time.substring(3,5))));
		
		category = item.getCategory();
		location = item.getLocation();
		done = item.isDone();

		// Change spinnerSelection from 0 if the category is not Personal
		if (category.equals("School")) {
			spinnerSelection = 1;
		}
		else if (category.equals("Work")) {
			spinnerSelection = 2;
		}
		else if (category.equals("Miscellaneous")) {
			spinnerSelection = 3;
		}
		spinner.setSelection(spinnerSelection);
	}
	
	/**
	 * Formats the time given in hours and minutes from 24- to 12-hour time.
	 * 
	 * @param hour
	 * 			the hours part of the time, base 24
	 * @param min
	 * 			the minutes part of the time
	 * @return the given time formatted to a 12-hour time, as a String
	 */
	private String formatTime(int hour, int min) {
		String middle = ":", ending;
		
		if (min < 10) {
			middle += "0";
		}
		if (hour > 12) {
			hour = hour - 12;
			ending = "pm";
		}
		else if (hour == 12) {
			ending = "pm";
		}
		else {
			if (hour == 0) {
				hour = 12;
			}
			ending = "am";
		}
		return hour + middle + min + ending;
	}

	/**
	 * Called when this Activity ends. Sets the itemRowID in Singleton to -1
	 * since it isn't needed anymore.
	 */
	@Override
	public void finish() {
		Singleton.getInstance().setItemRowID(-1);
		super.finish();
	}
	
	
}